import Foundation
import UIKit
import UniformTypeIdentifiers

/// BackDataLibrary - 提供iCloud数据备份和恢复功能
public class BackDataLibrary {
    
    /// 单例实例
    @MainActor public static let shared = BackDataLibrary()
    
    private init() {}
    
    /// 错误类型定义
    public enum BackupError: Error, LocalizedError {
        case iCloudNotAvailable
        case fileNotFound
        case copyFailed
        case permissionDenied
        case invalidPath
        
        public var errorDescription: String? {
            switch self {
            case .iCloudNotAvailable:
                return "iCloud不可用"
            case .fileNotFound:
                return "文件未找到"
            case .copyFailed:
                return "文件复制失败"
            case .permissionDenied:
                return "权限被拒绝"
            case .invalidPath:
                return "无效路径"
            }
        }
    }
    
    /// 检查iCloud是否可用
    /// - Returns: iCloud可用性状态
    public func isICloudAvailable() -> Bool {
        if let _ = FileManager.default.url(forUbiquityContainerIdentifier: nil) {
            return true
        }
        return false
    }
    
    /// 获取iCloud Documents目录
    /// - Returns: iCloud Documents目录URL，如果不可用则返回nil
    public func getICloudDocumentsDirectory() -> URL? {
        guard let iCloudURL = FileManager.default.url(forUbiquityContainerIdentifier: nil) else {
            return nil
        }
        return iCloudURL.appendingPathComponent("Documents")
    }
    
    /// 显示文件夹选择器，让用户选择iCloud备份路径
    /// - Parameters:
    ///   - presentingViewController: 用于展示选择器的视图控制器
    ///   - completion: 选择完成后的回调，返回选择的URL或错误
    @MainActor public func selectICloudBackupPath(
        from presentingViewController: UIViewController,
        completion: @escaping (Result<URL, BackupError>) -> Void
    ) {
        guard isICloudAvailable() else {
            completion(.failure(.iCloudNotAvailable))
            return
        }
        
        let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [.folder])
        documentPicker.allowsMultipleSelection = false
        documentPicker.directoryURL = getICloudDocumentsDirectory()
        
        // 创建一个临时的协调器来处理选择结果
        let coordinator = DocumentPickerCoordinator { urls in
            if let selectedURL = urls.first {
                completion(.success(selectedURL))
            } else {
                completion(.failure(.invalidPath))
            }
        }
        
        documentPicker.delegate = coordinator
        
        // 保持coordinator的引用，防止被释放
        objc_setAssociatedObject(documentPicker, "coordinator", coordinator, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        
        presentingViewController.present(documentPicker, animated: true)
    }
    
    /// 备份数据文件到指定的iCloud路径
    /// - Parameters:
    ///   - sourceFilePath: 源文件路径
    ///   - destinationURL: 目标iCloud路径
    ///   - fileName: 备份文件名（可选，默认使用源文件名）
    ///   - completion: 备份完成后的回调
    public func backupDataFile(
        from sourceFilePath: String,
        to destinationURL: URL,
        fileName: String? = nil,
        completion: @escaping (Result<URL, BackupError>) -> Void
    ) {
        let sourceURL = URL(fileURLWithPath: sourceFilePath)
        
        // 检查源文件是否存在
        guard FileManager.default.fileExists(atPath: sourceFilePath) else {
            completion(.failure(.fileNotFound))
            return
        }
        
        // 确定备份文件名
        let backupFileName = fileName ?? sourceURL.lastPathComponent
        let backupURL = destinationURL.appendingPathComponent(backupFileName)
        
        do {
            // 如果目标文件已存在，先删除
            if FileManager.default.fileExists(atPath: backupURL.path) {
                try FileManager.default.removeItem(at: backupURL)
            }
            
            // 复制文件到iCloud
            try FileManager.default.copyItem(at: sourceURL, to: backupURL)
            
            // 标记文件为iCloud同步
            try (backupURL as NSURL).setResourceValue(true, forKey: .hasHiddenExtensionKey)
            
            completion(.success(backupURL))
        } catch {
            completion(.failure(.copyFailed))
        }
    }
    
    /// 从iCloud恢复数据文件
    /// - Parameters:
    ///   - backupURL: 备份文件的iCloud URL
    ///   - destinationPath: 恢复到的本地路径
    ///   - completion: 恢复完成后的回调
    public func restoreDataFile(
        from backupURL: URL,
        to destinationPath: String,
        completion: @escaping (Result<String, BackupError>) -> Void
    ) {
        let destinationURL = URL(fileURLWithPath: destinationPath)
        
        // 检查备份文件是否存在
        guard FileManager.default.fileExists(atPath: backupURL.path) else {
            completion(.failure(.fileNotFound))
            return
        }
        
        do {
            // 如果目标文件已存在，先删除
            if FileManager.default.fileExists(atPath: destinationPath) {
                try FileManager.default.removeItem(at: destinationURL)
            }
            
            // 从iCloud复制文件到本地
            try FileManager.default.copyItem(at: backupURL, to: destinationURL)
            
            completion(.success(destinationPath))
        } catch {
            completion(.failure(.copyFailed))
        }
    }
    
    /// 列出指定iCloud目录下的所有备份文件
    /// - Parameters:
    ///   - directoryURL: iCloud目录URL
    ///   - fileExtension: 文件扩展名过滤（可选）
    ///   - completion: 完成后的回调，返回文件URL数组
    public func listBackupFiles(
        in directoryURL: URL,
        withExtension fileExtension: String? = nil,
        completion: @escaping (Result<[URL], BackupError>) -> Void
    ) {
        do {
            let fileURLs = try FileManager.default.contentsOfDirectory(
                at: directoryURL,
                includingPropertiesForKeys: [.creationDateKey, .fileSizeKey],
                options: [.skipsHiddenFiles]
            )
            
            var filteredURLs = fileURLs
            
            // 如果指定了文件扩展名，进行过滤
            if let ext = fileExtension {
                filteredURLs = fileURLs.filter { $0.pathExtension.lowercased() == ext.lowercased() }
            }
            
            // 按创建时间排序（最新的在前）
            filteredURLs.sort { url1, url2 in
                let date1 = (try? url1.resourceValues(forKeys: [.creationDateKey]))?.creationDate ?? Date.distantPast
                let date2 = (try? url2.resourceValues(forKeys: [.creationDateKey]))?.creationDate ?? Date.distantPast
                return date1 > date2
            }
            
            completion(.success(filteredURLs))
        } catch {
            completion(.failure(.invalidPath))
        }
    }
    
    /// 删除指定的备份文件
    /// - Parameters:
    ///   - backupURL: 要删除的备份文件URL
    ///   - completion: 删除完成后的回调
    public func deleteBackupFile(
        at backupURL: URL,
        completion: @escaping (Result<Void, BackupError>) -> Void
    ) {
        do {
            try FileManager.default.removeItem(at: backupURL)
            completion(.success(()))
        } catch {
            completion(.failure(.copyFailed))
        }
    }
}

/// 文档选择器协调器，用于处理UIDocumentPickerViewController的回调
private class DocumentPickerCoordinator: NSObject, UIDocumentPickerDelegate {
    private let completion: ([URL]) -> Void
    
    init(completion: @escaping ([URL]) -> Void) {
        self.completion = completion
        super.init()
    }
    
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        completion(urls)
    }
    
    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        completion([])
    }
}
